#include "stdafx.h"
#include <boost/test/auto_unit_test.hpp>
#include "bmock.hpp"
#include "bmock_control_tools_mock.hpp"
#include <sstream>

struct serialization_test_data3 {
	serialization_test_data3()
		:v1_(0)
		,v2_(0)
	{}
	serialization_test_data3(int v1,int v2)
		:v1_(v1)
		,v2_(v2)
	{}
	serialization_test_data3(const serialization_test_data3 &d)
		:v1_(d.v1_)
		,v2_(d.v2_)
	{}

	int v1_;
	int v2_;
};



struct serialization_test_data23 {
	serialization_test_data23()
		:data(NULL)
		,length(0)
	{}
	serialization_test_data23(int* v1,size_t v2,char* Str_,void* _data_=NULL)
		:data(v1)
		,length(v2)
		,Str(Str_)
		,data_(_data_)
	{}

	int* data; 
	size_t length;
	char* Str;
	void* data_;

};


namespace std {
	inline ostream &operator <<(ostream &os,const serialization_test_data3 &td) {
		os<<td.v1_<<' '<<td.v2_;
		std::string x;
		return os;
	}
	inline istream &operator >>(istream &is,serialization_test_data3 &td) {
		is>>td.v1_>>td.v2_; 
		return is;
	}
}


namespace std {
	inline ostream &operator <<(ostream &os,const serialization_test_data23 &td) {
		os<<*td.data;
		os<<' '<<td.length;
		os<<' ';
		os<<td.Str;
		os<<' ';
		os<<(unsigned char*)td.data_;
		return os;
	}
	inline istream &operator >>(istream &is,serialization_test_data23 &td) {
		char blank;
		bmock::get_buffer(td.data,1);
		is>>*td.data;
		is>>blank;
		is>>td.length;
		is>>blank;
		bmock::get_buffer(td.Str,9);
		is>>td.Str;
		is>>blank;
		bmock::get_buffer(td.data_,36);
		is>>(unsigned char*)td.data_;
		return is;
	}
}

enum MyEnumType3 { ALPHA, BETA, GAMMA };

static void f(const serialization_test_data3* x, serialization_test_data3* y, serialization_test_data3* z) {
	MOCK_VOID(3,(IN(x), OUT(y), IN_OUT(z)));
}
static void h(serialization_test_data23* y) {
	MOCK_VOID(1,(OUT(y)));
}
static void g(MyEnumType3& x) {
	MOCK_VOID(1, (IN_OUT(x)));
}
static void ga(MyEnumType3& x) {
	MOCK_VOID(1, (IN(x)));
}
static void gb(MyEnumType3& x) {
	MOCK_VOID(1, (OUT(x)));
}


static MyEnumType3 m=ALPHA;
static MyEnumType3 u=BETA;



BOOST_AUTO_TEST_CASE(test_serialization_ERROR3) {
	__BMOCK_CONTROL(c);
	const serialization_test_data3 d_in_(123,975);
	const serialization_test_data3 d_out_(537,910);
	serialization_test_data3       d1_(0,0);
	serialization_test_data3       d2_(d_in_);
	const bmock::control_tools_ptr       t(new bmock::control_tools_mock(c));
	const bmock::location                loc(__FILE__,__LINE__+13);

	__BMOCK_EXPECT_C(c,t->require_equal(2,2,bmock::message(bmock::IN_OUT_RAW_MEM_PAD_LEN,"z"),loc));
	__BMOCK_EXPECT_C(c,t->require_equal(2,2,bmock::message(bmock::IN_OUT_RAW_MEM_PAD_LEN,"z"),loc));
	__BMOCK_EXPECT_RETURN_C(c,false,t->check_equal("123 975","123 975",bmock::message(bmock::ARG_VALUE,"x"),loc));
	__BMOCK_EXPECT_RETURN_C(c,false,t->check_ptr(false,false,bmock::message(bmock::ARG_PTR,"z"),loc));
	__BMOCK_EXPECT_RETURN_C(c,false,t->check_equal("123 975","123 975",bmock::message(bmock::ARG_VALUE,"z"),loc));
	__BMOCK_EXPECT_RETURN_C(c,false,t->check_ptr(false,false,bmock::message(bmock::ARG_PTR,"y"),loc));
	__BMOCK_EXPECT_C(c,t->error(bmock::message(bmock::ARG_UPDATE,"y"),loc,false,false));
	__BMOCK_EXPECT_THROW_C(c,new bmock::location(loc),t->abort(loc));
	__BMOCK_REPLAY_C(c);
	{
		bmock::test_mode_control c1(bmock::location(__FILE__,__LINE__),t); __BMOCK_CREATE_MOCK_C((&c1),*);
		__BMOCK_EXPECT_C(c1,f(&d_in_,bmock::out_raw_mem(d_out_),bmock::in_out_raw_mem(d_in_,d_out_)));
		__BMOCK_REPLAY_C(c1);
		BOOST_CHECK_THROW(f(&d_in_,&d1_,&d2_),bmock::location);
	}
	__BMOCK_VERIFY_C(c);
}

BOOST_AUTO_TEST_CASE(test_serialization_enum_IN_OUT_Macro3) {
	__BMOCK_CONTROL(c);
	__BMOCK_CREATE_MOCK_C((&c),*);
	__BMOCK_EXPECT_C(c,g(bmock::in_out_raw_mem(m,m)));
	__BMOCK_REPLAY_C(c);
	BOOST_CHECK_NO_THROW(g(m));
	__BMOCK_VERIFY_C(c);

}

BOOST_AUTO_TEST_CASE(test_serialization_enum_INMacro3) {
	__BMOCK_CONTROL(c);
	__BMOCK_CREATE_MOCK_C((&c),*);
	__BMOCK_EXPECT_C(c,ga(m));
	__BMOCK_REPLAY_C(c);
	BOOST_CHECK_NO_THROW(ga(m));
	__BMOCK_VERIFY_C(c);

}

BOOST_AUTO_TEST_CASE(test_serialization_enum_OUT_Macro3) {
	__BMOCK_CONTROL(c);
	__BMOCK_CREATE_MOCK_C((&c),*);
	__BMOCK_EXPECT_C(c,gb(m));
	__BMOCK_REPLAY_C(c);
	BOOST_CHECK_NO_THROW(gb(u));
	__BMOCK_VERIFY_C(c);
	BOOST_CHECK_EQUAL(u,m);

}

BOOST_AUTO_TEST_CASE(test_de_serialization3) {
	int M=1;
	char N[9]={"checking"};
	int x[9]={1,2,3,4,5,6,7,8,9};
	int y[9]={7,2,3,4,5,7,7,7,9};
	serialization_test_data23 v(&M,8,N,x);
	serialization_test_data23 v2(&M,8,N,y);
	serialization_test_data23 v1;
	std::ostringstream        os;
	__BMOCK_CONTROL(c);
	__BMOCK_CREATE_MOCK_C((&c),*);
	__BMOCK_EXPECT_C(c,h(&v));
	__BMOCK_REPLAY_C(c);
	BOOST_CHECK_NO_THROW(h(&v1));
	__BMOCK_VERIFY_C(c);
	BOOST_CHECK_EQUAL(*v.data,*v1.data);
	BOOST_CHECK_EQUAL(v.length,v1.length);
	BOOST_CHECK_EQUAL(v.Str,v1.Str);
	BOOST_CHECK_EQUAL((char*)v1.data_,(char*)v.data_);

}




